import axios, { AxiosInstance, AxiosRequestConfig, AxiosResponse } from 'axios'
import { ElMessage } from 'element-plus'
import { Session } from '/@/utils/storage';
// import { getUserInfo, cleanSession } from '@/global/session'
// import { store } from '@/store'
// import router from '@/router'
import qs from 'qs'
import router from '../router';
import { ref } from 'vue';
//返回值类型
export interface Result<T = any> {
  code: number;
  msg: string;
  data: T;
}
const CancelToken = axios.CancelToken;

const msgFlag = ref(true)

class request {
  private instance: AxiosInstance;//axios实例
  //构造函数 给instance进行初始化
  constructor(config: AxiosRequestConfig) {
    //创建axios实例
    this.instance = axios.create(config);
    //拦截器配置
    this.interceptors()
  }
  private interceptors() {
    //请求发送之前的拦截器：添加token
    this.instance.interceptors.request.use((config: AxiosRequestConfig) => {
      //配置token
      const userInfo = Session.get('token')
      const token = userInfo ? userInfo : '';
      //如果token存在，放到请求的头部
      if (token && config.headers) {
        config.headers['API-User-Token'] = token
      }
      //强行中断请求
      config.cancelToken = new CancelToken(c => {
        // store.commit('http/setHttpList', c);
        // 忽略
      });
      return config;
    }, (error: any) => {
      // 错误抛到业务代码
      error.data = {}
      error.data.msg = '服务器异常，请联系管理员！'
      return error
    })
    //请求返回之后的处理
    this.instance.interceptors.response.use((res: AxiosResponse) => {
      if (res?.data) {
        const data = res.data;
        if (data.code == '40001' || data.code == '40002' || data.code == '40003') { //token过期
          Session.clear(); // 清除浏览器全部临时缓存
          ElMessage.error('监测您的token过期,请重新登录');
          router.replace({
            name: 'login',
            // 登录成功后跳入浏览的当前页面
            query: { redirect: router.currentRoute.value.fullPath }
          })
          // window.location.href = 'enterprisePC/index.html#/login'; // 去登录页
          ElMessage.error(data.message || '服务器出错!')
        } else if (data.code === 0) { //返回成功
          msgFlag.value = true
          return data
        } else if (res.config.responseType === 'arraybuffer') {
          ElMessage.success('导出成功')
          return data
        }
        else {
          ElMessage.error(data.message || '服务器出错!')
          return data || null;
        }
      } else {
        ElMessage.error('服务器出错!')
        return Promise.reject(res.data)
      }
    }, (error) => {
      if (error.message === 'interrupt') {
        console.log('请求中断');
        return new Promise(() => { });
      } else if (error && error.response) {
        error.data = {};
        switch (error.response.status) {
          case 400:
            error.data.msg = '错误请求';
            ElMessage.error(error.data.msg)
            break
          case 401:
            if (msgFlag.value) {
              Session.clear(); // 清除浏览器全部临时缓存
              ElMessage.error('检测到账号未授权，已返回登录页');
              router.replace({
                name: 'login',
                // 登录成功后跳入浏览的当前页面
                query: { redirect: router.currentRoute.value.fullPath }
              })
              msgFlag.value = false
            }
            break
          case 403:
            error.data.msg = '拒绝访问';
            ElMessage.error(error.data.msg)
            break
          case 404:
            error.data.msg = '请求错误,未找到该资源';
            ElMessage.error(error.data.msg)
            break
          case 405:
            error.data.msg = '请求方法未允许';
            ElMessage.error(error.data.msg)
            break
          case 408:
            error.data.msg = '请求超时';
            ElMessage.error(error.data.msg)
            break
          case 500:
            error.data.msg = '服务器端出错';
            ElMessage.error(error.data.msg)
            break
          case 501:
            error.data.msg = '网络未实现';
            ElMessage.error(error.data.msg)
            break
          case 502:
            error.data.msg = '网络错误';
            ElMessage.error(error.data.msg)
            break
          case 503:
            error.data.msg = '服务不可用';
            ElMessage.error(error.data.msg)
            break
          case 504:
            error.data.msg = '网络超时';
            ElMessage.error(error.data.msg)
            break
          case 505:
            error.data.msg = 'http版本不支持该请求';
            ElMessage.error(error.data.msg)
            break
          default:
            error.data.msg = `连接错误${error.response.status}`;
            ElMessage.error(error.data.msg)
        }
      } else {
        error.msg = "连接到服务器失败";
        ElMessage.error(error.msg)
      }
      return Promise.reject(error)
    })
  }
  //参数的处理
  getParams(params: any) {
    let url = '';
    if (Object.is(params, undefined || null)) {
      url = '';
    } else {
      for (const key in params) {
        if (params.hasOwnProperty(key) && params[key]) {
          url += `${params[key]}/`
        }
      }
    }
    if (url) {
      url = url.substring(0, url.length - 1);
    }
    return url;
  }
  //封装请求方法
  // get方法  http:localhost:8080/api/xxxx?userId=10  {userId : 10}
  get<T = any>(url: string, params?: any): Promise<Result<T>> {
    return new Promise((resolve, reject) => {
      this.instance.get<T>(url, {
        params: params,
        paramsSerializer: {
          serialize: (params: any) => {
            return qs.stringify(params)
          }
        }
      }).then((res) => {
        resolve(res as any)
      }).catch((error) => {
        reject(error)
      })
    })
  }
  // get方法  http:localhost:8080/api/xxxx/10  {userId : 10}
  getUrl<T = any>(url: string, params?: any): Promise<Result<T>> {
    return new Promise((resolve, reject) => {
      this.instance.get<T>(this.getParams(params) ? `${url}/${this.getParams(params)}` : url)
        .then((res) => {
          resolve(res as any)
        }).catch((error) => {
          reject(error)
        })
    })
  }
  getDown<T = any>(url: string, params?: any): Promise<Result<T>> {
    ElMessage({
      type: 'success',
      message: '资源请求中,请稍后'
    })
    return new Promise((resolve, reject) => {
      this.instance.get<T>(url, {
        params: params,
        paramsSerializer: {
          serialize: (params: any) => {
            return qs.stringify(params)
          }
        },
        responseType: 'arraybuffer'
      }).then((res) => {
        resolve(res as any)
      }).catch((error) => {
        reject(error)
      })
    })
  }
  // post方法 
  post<T = any>(url: string, params?: any): Promise<Result<T>> {
    return new Promise((resolve, reject) => {
      this.instance.post(url, params, {
        transformRequest: [(params) => {
          return JSON.stringify(params)
        }],
        headers: {
          'Content-Type': 'application/json'
        }
      }).then((res) => {
        resolve(res as any)
      }).catch((error) => {
        reject(error)
      })
    })
  }
  //application/x-www-form-urlencoded post方法
  postForm<T = any>(url: string, params?: any): Promise<Result<T>> {
    return new Promise((resolve, reject) => {
      this.instance.post<T>(url, params, {
        transformRequest: [(params) => {
          return qs.stringify(params)
        }],
        headers: {
          'Content-Type': 'application/x-www-form-urlencoded'
        }
      }).then((res) => {
        resolve(res as any)
      }).catch((error) => {
        reject(error)
      })
    })
  }
  // post方法 上传
  postUpload<T = any>(url: string, params?: any): Promise<Result<T>> {
    return new Promise((resolve, reject) => {
      this.instance.post(url, params, {
        headers: {
          'Content-Type': 'multipart/form-data'
        }
      }).then((res) => {
        resolve(res as any)
      }).catch((error) => {
        reject(error)
      })
    })
  }

  //post方法 获取数据流
  postBlob(url: string, params?: any) {
    ElMessage({
      type: 'success',
      message: '资源请求中,请稍后'
    })
    return this.instance.post(url, params, {
      responseType: 'arraybuffer'
    })
  }
  //put请求
  put<T = any>(url: string, params?: any): Promise<Result<T>> {
    return new Promise((resolve, reject) => {
      this.instance.put(url, params, {
        transformRequest: [(params) => {
          return JSON.stringify(params)
        }],
        headers: {
          'Content-Type': 'application/json'
        }
      }).then((res) => {
        resolve(res as any)
      }).catch((error) => {
        reject(error)
      })
    })
  }
  // put方法  http:localhost:8080/api/xxxx/10  {userId : 10}
  putUrlForm<T = any>(url: string, params?: any): Promise<Result<T>> {
    return new Promise((resolve, reject) => {
      this.instance.put<T>(this.getParams(params) ? `${url}/${this.getParams(params)}` : url, {
        headers: {
          'Content-Type': 'application/x-www-form-urlencoded'
        }
      })
        .then((res) => {
          resolve(res as any)
        }).catch((error) => {
          reject(error)
        })
    })
  }
  //put
  putForm<T = any>(url: string, params?: any): Promise<Result<T>> {
    return new Promise((resolve, reject) => {
      this.instance.put(url, params, {
        transformRequest: [(params) => {
          return qs.stringify(params)
        }],
        headers: {
          'Content-Type': 'application/x-www-form-urlencoded'
        }
      }).then((res) => {
        resolve(res as any)
      }).catch((error) => {
        reject(error)
      })
    })
  }
  //删除 http:localhost:8080/api/deleteById/10 {userId : 10}  ==>  10
  delete<T = any>(url: string, params?: any): Promise<Result<T>> {
    return new Promise((resolve, reject) => {
      this.instance.delete<T>(this.getParams(params) ? `${url}/${this.getParams(params)}` : url)
        .then((res) => {
          resolve(res as any)
        }).catch((error) => {
          reject(error)
        })
    })
  }
  // 删除 传data
  deleteForm<T = any>(url: string, params?: any): Promise<Result<T>> {
    return new Promise((resolve, reject) => {
      this.instance.delete<T>(url, {
        data: params,
        transformRequest: [(params) => {
          return qs.stringify(params)
        }],
        headers: {
          'Content-Type': 'application/x-www-form-urlencoded'
        }
      }).then((res) => {
        resolve(res as any)
      }).catch((error) => {
        reject(error)
      })
    })
  }

  deleteForm2<T = any>(url: string, params: any): Promise<Result<T>> {
    return new Promise((resolve, reject) => {
      this.instance.delete<T>(url, {
        data: params,
        // transformRequest: [(params) => {
        //   return qs.stringify(params)
        // }],
        headers: {
          'Content-Type': 'application/json'
        }
      }).then((res) => {
        resolve(res as any)
      }).catch((error) => {
        reject(error)
      })
    })
  }

  //删除 拼接地址 表单
  deleteUrlForm<T = any>(url: string, params?: any): Promise<Result<T>> {
    return new Promise((resolve, reject) => {
      this.instance.delete<T>(this.getParams(params) ? `${url}/${this.getParams(params)}` : url, {
        headers: {
          'Content-Type': 'application/x-www-form-urlencoded'
        }
      })
        .then((res) => {
          resolve(res as any)
        }).catch((error) => {
          reject(error)
        })
    })
  }
}
export default request;